package main

import (
    "fmt"
    "time"
)

type StoreSet []Store

func (sm StoreSet) FilterByTable(appid, tableName string) StoreSet {
    var ret []Store
    for _, s := range sm {
        if s.GetTableDef().Appid == appid && s.GetTableDef().TableName == tableName {
            ret = append(ret, s)
        }
    }
    return StoreSet(ret)
}

func (sm StoreSet) FilterByPartition(partition, dtPrefix string) StoreSet {
    var ret []Store
    for _, s := range sm {
        if s.GetPartition().Matches(partition, dtPrefix) {
            ret = append(ret, s)
        }
    }
    return StoreSet(ret)
}

func (sm StoreSet) FilterByActive(o, r, w int64) StoreSet {
    var ret []Store
    now := time.Now().Unix()
    for _, s := range sm {
        ot, rt, wt := s.LastActiveTime()
        if (ot != 0 && now-ot > o) || (rt != 0 && now-rt > o) || (wt != 0 && now-wt > w) {
            ret = append(ret, s)
        }
    }
    return StoreSet(ret)
}

func (sm StoreSet) GetOrCreate(td TableDefine, par Partition, bp string) (Store, bool, error) {
    if td.DtLength != len(par.dt) {
        return nil, false, fmt.Errorf("td length not match")
    }
    subset := sm.FilterByTable(td.Appid, td.TableName)
    if len(subset) != 0 && !td.IsSame(subset[0].GetTableDef()) {
        return nil, false, fmt.Errorf("existing table define not match")
    }
    subset = subset.FilterByPartition(par.partition, par.dt)
    switch len(subset) {
    case 0:
        s, err := DefaultStoreFunc(td, par, bp) //NewRocksdbStore(td, par)
        if err != nil {
            return nil, false, err
        }
        return s, true, nil
    case 1:
        return subset[0], false, nil
    default:
        return nil, false, fmt.Errorf("existing duplicated partition found")
    }
}

func (sm StoreSet) MustAdd(store Store) StoreSet {
    td := store.GetTableDef()
    par := store.GetPartition()
    subset := sm.FilterByTable(td.Appid, td.TableName).FilterByPartition(par.partition, par.dt)
    if len(subset) == 0 {
        return append(sm, store)
    }
    return sm
}
